﻿Imports WSEntidades
Imports Utilerias
Imports WSDatos
Imports System.Transactions

Public Class ProductoBL
    Private tokenEncrip As String = ""

    Private Sub almacenaImagen(ByVal img As Byte(), ByVal ruta As String, ByVal nombreImagen As String, ByRef msg As String)
        Try
            If (img Is Nothing) Then
                'Verificar si en la ruta ya habia un archivo con el nombre, porque si es actualizacion y se quiere eliminar la imagen hay que borrarla del dd
                If (System.IO.File.Exists(System.IO.Path.Combine(ruta, nombreImagen & ".jpg"))) Then
                    System.IO.File.Delete(System.IO.Path.Combine(ruta, nombreImagen & ".jpg"))
                End If
            Else
                If (Not System.IO.Directory.Exists(ruta)) Then
                    System.IO.Directory.CreateDirectory(ruta)
                End If
                If (csArchivos.escribeArchivoDesdeBytearray(ruta,
                                            nombreImagen & ".jpg",
                                            img) = "") Then
                    msg &= "Error al almacenar imagen del producto." & vbCrLf
                End If
            End If
        Catch ex As Exception
            Log.LogException(ex, "ProductoBL.almacenaImagen")
            msg &= "Error al procesar operacion con imagen del producto." & vbCrLf
        End Try
    End Sub

    Public Function RegistrarProducto(ByVal TokenConexion As String, ByVal Producto As ProductoBE, ByVal ProductoAdic As ProductoAdicBE,
                                      ByRef detResp As DetalleRespuesta) As Boolean
        Dim ProductoDAL As ProductoDAL = New ProductoDAL("")
        Dim emprBL As EmpresasBL = New EmpresasBL()
        Dim boolTransaccionCompletada As Boolean = False
        Dim rfc As String = ""
        detResp.Mensajes = ""
        Try
            tokenEncrip = TokenConexion
            TokenConexion = RijndaelSimple.desencriptaDefault(TokenConexion)
            If (EsValidoPara(Enumeraciones.operacionesCatalogos.Registrar, Producto, ProductoAdic, detResp.Mensajes)) Then
                ProductoDAL = New ProductoDAL(TokenConexion)
                rfc = emprBL.getRFCEmpresa(RijndaelSimple.encriptaDefault(TokenConexion))
                If (ProductoDAL.existeProducto(Producto.Clave)) Then
                    detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.Catalogo_PreviamenteRegistrado,
                                             "Existe un registro con la clave del Producto indicado." & vbCrLf & detResp.Mensajes)
                    Return False
                Else
                    Using transacCta As TransactionScope = New TransactionScope()
                        If (ProductoDAL.registraProducto(Producto)) Then
                            If (ProductoAdic Is Nothing) Then
                                boolTransaccionCompletada = True
                            Else
                                If (ProductoDAL.registrarOActualizarProductoAdic(ProductoAdic, Producto.Clave)) Then
                                    boolTransaccionCompletada = True
                                End If
                            End If
                            If (boolTransaccionCompletada) Then
                                transacCta.Complete()
                                'Almacenar la imagen del producto si existe
                                Me.almacenaImagen(Producto.Imagen,
                                                  System.IO.Path.Combine(My.Settings.PathFiles, rfc, "productos"),
                                                  Producto.Clave,
                                                  detResp.Mensajes)
                                'If (Producto.Imagen IsNot Nothing) Then
                                '    If (Not System.IO.Directory.Exists(System.IO.Path.Combine(My.Settings.PathFiles, rfc, "productos"))) Then
                                '        System.IO.Directory.CreateDirectory(System.IO.Path.Combine(My.Settings.PathFiles, rfc, "productos"))
                                '    End If
                                '    If (csArchivos.escribeArchivoDesdeBytearray(System.IO.Path.Combine(My.Settings.PathFiles, rfc, "productos"),
                                '                                Producto.Clave & ".jpg",
                                '                                Producto.Imagen) = "") Then
                                '        detResp.Mensajes &= "Error al almacenar imagen del producto." & vbCrLf
                                '    End If
                                'End If
                                detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ProcesamientoOK, "El Producto se registro con éxito.")
                                Return True
                            Else
                                detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.Catalogo_NoFueRegistrado,
                                                 "El Producto no pudo ser registrado en el sistema." & vbCrLf & detResp.Mensajes)
                                Return False
                            End If
                        Else
                            detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.Catalogo_NoFueRegistrado,
                                                 "El Producto no pudo ser registrado en el sistema." & vbCrLf & detResp.Mensajes)
                            Return False
                        End If
                    End Using
                End If
            Else
                detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ValoresInvalidos,
                                         "El Producto no es valido para registrar: " & vbCrLf & detResp.Mensajes)
                Return False
            End If
        Catch ex As Exception
            Log.LogException(ex, "ProductoBL.RegistrarProducto")
            detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ExcepcionEnOperacion,
                                        detResp.Mensajes & "Excepción al registrar Producto: " & ex.Message)
            Return False
        Finally
            ProductoDAL = Nothing
            emprBL = Nothing
            boolTransaccionCompletada = Nothing
            rfc = Nothing
        End Try
    End Function

    Private Function EsValidoPara(ByVal tipoOperacion As Enumeraciones.operacionesCatalogos, ByRef Producto As ProductoBE, ByRef ProductoAdic As ProductoAdicBE, ByRef mensaje As String) As Boolean
        mensaje = ""
        Dim unidMedBL As UdeMBL = New UdeMBL()
        Dim tipoProdBL As TiposProductosBL = New TiposProductosBL()
        Dim ubicBL As UbicacionBL = New UbicacionBL()
        Dim provBL As ProveedoresBL = New ProveedoresBL()
        Dim prodDAL As ProductoDAL = New ProductoDAL(RijndaelSimple.desencriptaDefault(Me.tokenEncrip))
        Try
            If (String.IsNullOrWhiteSpace(Producto.Clave)) Then
                mensaje &= "La Clave del Producto es obligatoria, no puede ir el campo vacio." & vbCrLf
            Else
                Producto.Clave = Producto.Clave.Trim
                If (Producto.Clave.Length > 50) Then
                    Producto.Clave = Producto.Clave.Substring(0, 50)
                End If
            End If
            If (String.IsNullOrWhiteSpace(Producto.Nombre)) Then
                mensaje &= "El Nombre del Producto es obligatorio, no puede ir el campo vacio." & vbCrLf
            Else
                Producto.Nombre = Producto.Nombre.Trim
                If (Producto.Nombre.Length > 255) Then
                    Producto.Nombre = Producto.Nombre.Substring(0, 255)
                End If
            End If
            If (Not String.IsNullOrWhiteSpace(Producto.Descripcion)) Then
                Producto.Descripcion = Producto.Descripcion.Trim
                If (Producto.Descripcion.Length > 32000) Then
                    Producto.Descripcion = Producto.Descripcion.Substring(0, 32000)
                End If
            End If
            If Not (String.IsNullOrWhiteSpace(Producto.Observaciones)) Then
                Producto.Observaciones = Producto.Observaciones.Trim
                If (Producto.Observaciones.Length > 5000) Then
                    Producto.Observaciones = Producto.Observaciones.Substring(0, 5000)
                End If
            End If

            If (Producto.UdeM Is Nothing) Then
                mensaje &= "La Unidad de Medida del Producto es obligatoria, no puede ir el campo vacio." & vbCrLf
            Else
                If (Producto.UdeM.IdUdeM <= 0) Then
                    mensaje &= "La Unidad de Medida del Producto debe ser mayor a 0 y estar previamente registrada en el sistema." & vbCrLf
                Else
                    If (unidMedBL.GetUdeM(Me.tokenEncrip, Producto.UdeM.IdUdeM, New DetalleRespuesta) Is Nothing) Then
                        mensaje &= "La Unidad de Medida con Id <" & Producto.UdeM.IdUdeM.ToString() & "> no esta registrada en el sistema." & vbCrLf
                    End If
                End If
            End If


            If (Producto.DesglosaPrecio) Then
                'Si desglosa precio, debe contener valores en mano de obra y refacciones, y se debe calcular el precio unitario
                If (Producto.ManoObra = Nothing) Then
                    mensaje &= "El precio de Mano de Obra del Producto es requerido al desglosar precios." & vbCrLf
                End If
                If (Producto.Refacciones = Nothing) Then
                    mensaje &= "El precio de Refacciones del Producto es requerido al desglosar precios." & vbCrLf
                End If
                If (Producto.ManoObra <> Nothing And Producto.Refacciones <> Nothing) Then
                    Producto.PrecioUnitario = Producto.ManoObra + Producto.Refacciones
                End If
            Else
                'No desglosa precio, se setean en 0 el precio de refacciones y mano de obra y se toma en cuenta el precio unitario sin cambiar
                Producto.ManoObra = 0D
                Producto.Refacciones = 0D
                If (Producto.PrecioUnitario = Nothing) Then
                    mensaje &= "El Precio unitario del Producto es requerido." & vbCrLf
                End If
            End If

            If (Producto.TipoBaseIVA = Enumeraciones.tipoBaseParaIVA.Porcentaje) Then
                'Si la base del IVA es por porcentaje, debe traer el valor de ese porcentaje
                If (String.IsNullOrWhiteSpace(Producto.PorcentajeBaseIVA)) Then
                    mensaje &= "El Porcentaje base para calculo de IVA es requerido." & vbCrLf
                Else
                    If Not (IsNumeric(Producto.PorcentajeBaseIVA)) Then
                        mensaje &= "El Porcetanje de IVA del Producto debe ser de tipo numérico." & vbCrLf
                    Else
                        If (Producto.PorcentajeBaseIVA < 0 Or Producto.PorcentajeBaseIVA > 100) Then
                            mensaje &= "El Porcentaje Base de IVA del Producto debe ser un valor entre 0% y 100%." & vbCrLf
                        End If
                    End If
                End If
                'El monto se deja en el valor del precio unitario
                Producto.MontoBaseIVA = Producto.PrecioUnitario
            Else
                'Si la base del IVA es por monto, debe traer el valor del monto
                If (String.IsNullOrWhiteSpace(Producto.MontoBaseIVA)) Then
                    mensaje &= "El Monto base para el calculo de IVA es requerido." & vbCrLf
                Else
                    If Not (IsNumeric(Producto.MontoBaseIVA)) Then
                        mensaje &= "El Monto base de Iva del Producto debe ser de tipo numérico." & vbCrLf
                    Else
                        If (Producto.MontoBaseIVA < 0 Or Producto.MontoBaseIVA > Producto.PrecioUnitario) Then
                            mensaje &= "El Monto base de IVA debe ser mayor a 0 y menor al Precio Unitario del Producto." & vbCrLf
                        End If
                        Producto.MontoBaseIVA = Decimal.Parse(Producto.MontoBaseIVA).ToString("N6")
                    End If
                End If
                'El porcentaje base iva se deja en 100
                Producto.PorcentajeBaseIVA = 100
            End If

            Select Case Producto.AplicaIEPS
                Case Enumeraciones.tipoAplicacionIEPS.NoAplica
                    Producto.IEPSAfectaIVA = False
                    Producto.CuotaIEPS = 0
                    Producto.TasaIEPS = 0

                Case Enumeraciones.tipoAplicacionIEPS.PorTasa
                    'Se requiere valor en tasa
                    If (String.IsNullOrWhiteSpace(Producto.TasaIEPS)) Then
                        mensaje &= "La Tasa de IEPS del Producto es requerida." & vbCrLf
                    Else
                        If Not (IsNumeric(Producto.TasaIEPS)) Then
                            mensaje &= "La Tasa de IEPS del Producto debe ser de tipo numérico." & vbCrLf
                        Else
                            If (Producto.TasaIEPS <= 0 Or Producto.TasaIEPS > 300) Then
                                mensaje &= "Especifique una Tasa válida para el IEPS del producto." & vbCrLf
                            End If
                        End If
                    End If
                    Producto.CuotaIEPS = 0

                Case Enumeraciones.tipoAplicacionIEPS.PorCuota
                    'Se requiere valor en cuota
                    If (String.IsNullOrWhiteSpace(Producto.CuotaIEPS)) Then
                        mensaje &= "La Cuota de IEPS del Producto es requerida." & vbCrLf
                    Else
                        If Not (IsNumeric(Producto.CuotaIEPS)) Then
                            mensaje &= "La Cuota de IEPS del Producto debe ser de tipo numérico." & vbCrLf
                        Else
                            If (Producto.CuotaIEPS <= 0 Or Producto.CuotaIEPS > Producto.PrecioUnitario) Then
                                mensaje &= "La Cuota del IEPS debe ser un valor mayor a 0 pero menor o igual al Precio Unitario del Producto." & vbCrLf
                            End If
                        End If
                    End If
                    Producto.TasaIEPS = 0
            End Select

            If (Producto.AplicaIVARET) Then
                If (String.IsNullOrWhiteSpace(Producto.TasaIVARET)) Then
                    mensaje &= "La Tasa de IVA Retenido del Producto es requerida." & vbCrLf
                Else
                    If Not (IsNumeric(Producto.TasaIVARET)) Then
                        mensaje &= "La Tasa de IVA Retenido del Producto debe ser de tipo numérico." & vbCrLf
                    Else
                        If ((Producto.TasaIVARET < 0 OrElse Producto.TasaIVARET > 100)) Then
                            mensaje &= "La Tasa de IVA Retenido del Producto debe estar entre el 0% y el 100%." & vbCrLf
                        End If
                    End If
                End If
            Else
                Producto.TasaIVARET = 0D
            End If

            If (Producto.AplicaISR) Then
                If (String.IsNullOrWhiteSpace(Producto.TasaISR)) Then
                    mensaje &= "La Tasa de ISR del Producto es requerida." & vbCrLf
                Else
                    If Not (IsNumeric(Producto.TasaISR)) Then
                        mensaje &= "La Tasa de ISR del Producto debe ser de tipo numérico." & vbCrLf
                    Else
                        If ((Producto.TasaISR < 0 OrElse Producto.TasaISR > 100)) Then
                            mensaje &= "La Tasa de ISR del Producto debe estar entre el 0% y el 100%." & vbCrLf
                        End If
                    End If
                End If
            Else
                Producto.TasaISR = 0D
            End If

            If (Producto.Es = ProductoBE.EsProducto.Inmueble) Then
                If (String.IsNullOrWhiteSpace(Producto.Predial)) Then
                    mensaje &= "El Predial es requerido para un Inmueble." & vbCrLf
                End If
            End If
            If Not (String.IsNullOrWhiteSpace(Producto.Predial)) Then
                Producto.Predial = Producto.Predial.Trim
                If (Producto.Predial.Length > 50) Then
                    Producto.Predial = Producto.Predial.Substring(0, 50)
                End If
            End If
            If Not (String.IsNullOrWhiteSpace(Producto.CodigoBarras)) Then
                Producto.CodigoBarras = Producto.CodigoBarras.Trim
                If (Producto.CodigoBarras.Length > 50) Then
                    Producto.CodigoBarras = Producto.CodigoBarras.Substring(0, 50)
                End If
            End If

            ' ===================================================================================
            ' ======>>>>>>>> VALIDACION DE OBJETO PRODUCTOADICIONALESBE  <<<<<<<<<<<=============
            ' ===================================================================================

            If (ProductoAdic IsNot Nothing) Then
                'VALIDAR EL OBJETO DE DATOS ADICIONALES
                If (String.IsNullOrWhiteSpace(ProductoAdic.Clave)) Then
                    mensaje &= "La Clave de Adicionales del producto es requerida." & vbCrLf
                Else
                    ProductoAdic.Clave = ProductoAdic.Clave.Trim()
                    If (Not String.IsNullOrWhiteSpace(Producto.Clave) AndAlso (Producto.Clave <> ProductoAdic.Clave)) Then
                        mensaje &= "La Clave del producto es diferente de la Clave de los Adicionales, favor de verificar." & vbCrLf
                    End If
                End If

                If (ProductoAdic.TipoProducto IsNot Nothing) Then
                    If (ProductoAdic.TipoProducto.Id <= 0) Then
                        mensaje &= "El Tipo de Producto y Familia de Producto deben estar registrados previamente en el sistema." & vbCrLf
                    Else
                        'Validar que el ID de tipo exista en la bd
                        If Not (tipoProdBL.ExisteTipoProductoPorID(Me.tokenEncrip, ProductoAdic.TipoProducto.Id)) Then
                            mensaje &= "El Tipo de Producto no esta registrado en el sistema." & vbCrLf
                        End If
                    End If
                End If

                If Not (String.IsNullOrWhiteSpace(ProductoAdic.StockMax)) Then
                    If Not (IsNumeric(ProductoAdic.StockMax)) Then
                        mensaje &= "El Stock Máximo del Producto debe ser de tipo numérico." & vbCrLf
                    Else
                        If (ProductoAdic.StockMax < 0) Then
                            mensaje &= "El Stock Máximo no puede ser menor a 0." & vbCrLf
                        End If
                    End If
                End If

                If Not (String.IsNullOrWhiteSpace(ProductoAdic.StockMin)) Then
                    If Not (IsNumeric(ProductoAdic.StockMin)) Then
                        mensaje &= "El Stock Mínimo del Producto debe ser de tipo numérico." & vbCrLf
                    ElseIf (ProductoAdic.StockMin < 0) Then
                        mensaje &= "El Stock Mínimo no puede ser menor a 0." & vbCrLf
                    End If
                End If

                If Not (String.IsNullOrWhiteSpace(ProductoAdic.PuntoReorden)) Then
                    If Not (IsNumeric(ProductoAdic.PuntoReorden)) Then
                        mensaje &= "El Punto de Reorden del Producto debe ser de tipo numérico." & vbCrLf
                    ElseIf (ProductoAdic.PuntoReorden < 0) Then
                        mensaje &= "El Punto de Reorden del Producto no puede ser menor a 0." & vbCrLf
                    End If
                End If

                If (Not String.IsNullOrWhiteSpace(ProductoAdic.StockMax) Or _
                    Not String.IsNullOrWhiteSpace(ProductoAdic.StockMin) Or _
                    Not String.IsNullOrWhiteSpace(ProductoAdic.PuntoReorden)) Then
                    'Tienen que estar todos, si falta alguno hay que pedir que esten los valores
                    If (Not String.IsNullOrWhiteSpace(ProductoAdic.StockMax) And _
                        Not String.IsNullOrWhiteSpace(ProductoAdic.StockMin) And _
                        Not String.IsNullOrWhiteSpace(ProductoAdic.PuntoReorden)) Then
                        If (IsNumeric(ProductoAdic.StockMax) AndAlso _
                            IsNumeric(ProductoAdic.StockMin) AndAlso _
                            IsNumeric(ProductoAdic.PuntoReorden)) Then
                            If Not (ProductoAdic.StockMin <= ProductoAdic.PuntoReorden And ProductoAdic.PuntoReorden <= ProductoAdic.StockMax) Then
                                mensaje &= "El Punto de Reorden debe ser mayor o igual al Stock Mínimo, y el Stock Máximo debe ser mayor o igual al Punto de Reorden." & vbCrLf
                            End If
                        Else
                            mensaje &= "Stock Máximo, Mínimo y Punto de reorden deben ser de tipo numérico." & vbCrLf
                        End If
                    Else
                        mensaje &= "Debe espeficiar el Stock Máximo, Mínimo y el Punto de reorden." & vbCrLf
                    End If
                End If

                If (tipoOperacion = Enumeraciones.operacionesCatalogos.Registrar) Then
                    If Not (String.IsNullOrWhiteSpace(ProductoAdic.CostoPromedio)) Then
                        If Not (IsNumeric(ProductoAdic.CostoPromedio)) Then
                            mensaje &= "El Costo Promedio del Producto debe ser de tipo numérico." & vbCrLf
                        ElseIf (ProductoAdic.CostoPromedio < 0) Then
                            mensaje &= "El Costo Promedio del Producto no puede ser menor a 0." & vbCrLf
                        End If
                    Else
                        mensaje &= "El Costo Promedio del Producto es requerido." & vbCrLf
                    End If

                    If Not (String.IsNullOrWhiteSpace(ProductoAdic.UltimoCosto)) Then
                        If Not (IsNumeric(ProductoAdic.UltimoCosto)) Then
                            mensaje &= "El Ultimo Costo del Producto debe ser de tipo numérico." & vbCrLf
                        ElseIf (ProductoAdic.UltimoCosto < 0) Then
                            mensaje &= "El Ultimo Costo del Producto no puede ser menor a 0." & vbCrLf
                        End If
                    Else
                        mensaje &= "El Ultimo Costo del Producto es requerido." & vbCrLf
                    End If
                Else
                    'En la actualización no se deben modificar estos valores sino que se recalculan en base a las compras (entradas)
                    ProductoAdic.CostoPromedio = 0D
                    ProductoAdic.UltimoCosto = 0D
                End If

                If (ProductoAdic.UnidadEntrada Is Nothing OrElse ProductoAdic.UnidadEntrada.IdUdeM <= 0) Then
                    mensaje &= "La Unidad de Entrada del Producto es requerida." & vbCrLf
                Else
                    If (unidMedBL.GetUdeM(Me.tokenEncrip, ProductoAdic.UnidadEntrada.IdUdeM, New DetalleRespuesta) Is Nothing) Then
                        mensaje &= "La Unidad de Medida de entrada con Id <" & ProductoAdic.UnidadEntrada.IdUdeM.ToString() & "> no esta registrada en el sistema." & vbCrLf
                    End If
                End If

                If Not (String.IsNullOrWhiteSpace(ProductoAdic.FactorConversion)) Then
                    If Not (IsNumeric(ProductoAdic.FactorConversion)) Then
                        mensaje &= "El Factor de Conversión del Producto debe ser de tipo numérico." & vbCrLf
                    ElseIf (ProductoAdic.FactorConversion <= 0) Then
                        mensaje &= "El Factor de Conversión del Producto debe ser mayor a 0." & vbCrLf
                    End If
                Else
                    mensaje &= "El Factor de Conversión entre la Unidad de Entrada y la Unidad de Salida es requerido." & vbCrLf
                End If

                If (Producto.UdeM IsNot Nothing AndAlso ProductoAdic.UnidadEntrada IsNot Nothing) Then
                    If (Producto.UdeM.IdUdeM = ProductoAdic.UnidadEntrada.IdUdeM) Then
                        If (Not String.IsNullOrWhiteSpace(ProductoAdic.FactorConversion) AndAlso ProductoAdic.FactorConversion <> 1) Then
                            mensaje &= "El Factor de Conversión debe ser 1 para la Unidad de Entrada que es la misma que la Unidad de Salida." & vbCrLf
                        End If
                    End If
                End If

                If (ProductoAdic.Ubicacion1 IsNot Nothing) Then
                    If (ProductoAdic.Ubicacion1.IdUbicacion <= 0) Then
                        mensaje &= "La Ubicación1 del Producto debe existir en el sistema." & vbCrLf
                    Else
                        If (ubicBL.GetUbicacion(Me.tokenEncrip, ProductoAdic.Ubicacion1.IdUbicacion, New DetalleRespuesta) Is Nothing) Then
                            mensaje &= "La Ubicación1 <" & ProductoAdic.Ubicacion1.IdUbicacion & "> del Producto no está registrada en el sistema." & vbCrLf
                        End If
                    End If
                End If
                If (ProductoAdic.Ubicacion2 IsNot Nothing) Then
                    If (ProductoAdic.Ubicacion2.IdUbicacion <= 0) Then
                        mensaje &= "La Ubicación2 del Producto debe existir en el sistema." & vbCrLf
                    Else
                        If (ubicBL.GetUbicacion(Me.tokenEncrip, ProductoAdic.Ubicacion2.IdUbicacion, New DetalleRespuesta) Is Nothing) Then
                            mensaje &= "La Ubicación2 <" & ProductoAdic.Ubicacion2.IdUbicacion & "> del Producto no está registrada en el sistema." & vbCrLf
                        End If
                    End If
                End If
                If (ProductoAdic.Ubicacion3 IsNot Nothing) Then
                    If (ProductoAdic.Ubicacion3.IdUbicacion <= 0) Then
                        mensaje &= "La Ubicación3 del Producto debe existir en el sistema." & vbCrLf
                    Else
                        If (ubicBL.GetUbicacion(Me.tokenEncrip, ProductoAdic.Ubicacion3.IdUbicacion, New DetalleRespuesta) Is Nothing) Then
                            mensaje &= "La Ubicación3 <" & ProductoAdic.Ubicacion3.IdUbicacion & "> del Producto no está registrada en el sistema." & vbCrLf
                        End If
                    End If
                End If

                If (ProductoAdic.Proveedor1 IsNot Nothing) Then
                    If (ProductoAdic.Proveedor1.IdPro <= 0) Then
                        mensaje &= "El Proveedor1 del Producto debe existir en el sistema." & vbCrLf
                    Else
                        If (provBL.GetProveedor(Me.tokenEncrip, ProductoAdic.Proveedor1.CvePro, New DetalleRespuesta) Is Nothing) Then
                            mensaje &= "El Proveedor1 <" & ProductoAdic.Proveedor1.CvePro & "> no está registrado en el sistema." & vbCrLf
                        End If
                    End If
                End If
                If (ProductoAdic.Proveedor2 IsNot Nothing) Then
                    If (ProductoAdic.Proveedor2.IdPro <= 0) Then
                        mensaje &= "El Proveedor2 del Producto debe existir en el sistema." & vbCrLf
                    Else
                        If (provBL.GetProveedor(Me.tokenEncrip, ProductoAdic.Proveedor2.CvePro, New DetalleRespuesta) Is Nothing) Then
                            mensaje &= "El Proveedor2 <" & ProductoAdic.Proveedor2.CvePro & "> no está registrado en el sistema." & vbCrLf
                        End If
                    End If
                End If
            Else
                'Si es actualizacion hay que verificar que efectivamente no haya registro de datos adicionales, 
                'si hay datos adicionales en bd pero no se envian al actualizar, no se debe proceder
                If (tipoOperacion = Enumeraciones.operacionesCatalogos.Actualizar) Then
                    If (prodDAL.existeProductoAdic(Producto.Clave)) Then
                        mensaje &= "Falta la especificación de los datos adicionales del Producto." & vbCrLf
                    End If
                End If
            End If

            Return (mensaje = "")
        Catch ex As Exception
            Log.LogException(ex, "ProductoBL.EsValidoParaRegistrar")
            mensaje &= ex.Message
            Return False
        End Try
    End Function

    Public Function ActualizaProducto(ByVal TokenConexion As String, ByVal Producto As ProductoBE, ByVal ProductoAdic As ProductoAdicBE,
                                      ByRef detResp As DetalleRespuesta) As Boolean
        detResp.Mensajes = ""
        Dim ProductoDAL As ProductoDAL = New ProductoDAL("")
        Dim boolTransComplete As Boolean = False
        Dim emprBL As EmpresasBL = New EmpresasBL()
        Dim rfc As String = ""
        Try
            Me.tokenEncrip = TokenConexion
            TokenConexion = RijndaelSimple.desencriptaDefault(TokenConexion)
            If (EsValidoPara(Enumeraciones.operacionesCatalogos.Actualizar, Producto, ProductoAdic, detResp.Mensajes)) Then
                ProductoDAL = New ProductoDAL(TokenConexion)
                rfc = emprBL.getRFCEmpresa(RijndaelSimple.encriptaDefault(TokenConexion))
                Using transacCta As TransactionScope = New TransactionScope()
                    If (ProductoDAL.actualizaProducto(Producto)) Then
                        If (ProductoAdic Is Nothing) Then
                            boolTransComplete = True
                        Else
                            If (ProductoDAL.registrarOActualizarProductoAdic(ProductoAdic, Producto.Clave)) Then
                                boolTransComplete = True
                            End If
                        End If
                        If (boolTransComplete) Then
                            transacCta.Complete()
                            'Almacenar la imagen del producto si existe
                            Me.almacenaImagen(Producto.Imagen,
                                              System.IO.Path.Combine(My.Settings.PathFiles, rfc, "productos"),
                                              Producto.Clave,
                                              detResp.Mensajes)
                            detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ProcesamientoOK, "Datos de Producto actualizados.")
                            Return True
                        Else
                            detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.Catalogo_NoFueActualizado,
                                                     "No se pudo realizar la actualización de Datos de Producto (Transacción no completada)." & vbCrLf & detResp.Mensajes)
                            Return False
                        End If
                    Else
                        detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.Catalogo_NoFueActualizado,
                                                     "No se pudo realizar la actualización de Datos de Producto." & vbCrLf &
                                                     "Verifique que la Clave del Producto esté registrada en el sistema." & vbCrLf & detResp.Mensajes)
                        Return False
                    End If
                End Using
            Else
                detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ValoresInvalidos,
                                         "La informacion no es valida para actualizar: " & vbCrLf & detResp.Mensajes)
                Return False
            End If
        Catch ex As Exception
            Log.LogException(ex, "ProductoBL.ActualizaProducto")
            detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ExcepcionEnOperacion,
                                        detResp.Mensajes & "Excepción al actualizar Producto: " & ex.Message)
            Return False
        Finally
            ProductoDAL = Nothing
            boolTransComplete = Nothing
            emprBL = Nothing
            rfc = Nothing
        End Try
    End Function

    Public Function GetProducto(ByVal tokenConexion As String, ByVal Clave As String, ByRef ProductoAdic As ProductoAdicBE,
                                ByRef detResp As DetalleRespuesta) As ProductoBE
        detResp.Mensajes = ""
        Dim ProductoDAL As ProductoDAL = New ProductoDAL("")
        Dim ProductoBE As ProductoBE
        Dim emprBL As EmpresasBL = New EmpresasBL()
        Dim rfc As String = ""
        Try
            tokenConexion = RijndaelSimple.desencriptaDefault(tokenConexion)
            If (EsValidoParaGetProducto(Clave, detResp.Mensajes)) Then
                rfc = emprBL.getRFCEmpresa(RijndaelSimple.encriptaDefault(tokenConexion))
                ProductoDAL = New ProductoDAL(tokenConexion)
                ProductoBE = ProductoDAL.getProducto(Clave, ProductoAdic)
                If (ProductoBE IsNot Nothing) Then
                    If (System.IO.File.Exists(System.IO.Path.Combine(My.Settings.PathFiles, rfc, "productos", ProductoBE.Clave & ".jpg"))) Then
                        ProductoBE.Imagen = csArchivos.leeArchivoEnByteArray(System.IO.Path.Combine(My.Settings.PathFiles, rfc, "productos", ProductoBE.Clave & ".jpg"))
                    Else
                        ProductoBE.Imagen = Nothing
                    End If
                    detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ProcesamientoOK,
                                             "Se obtuvo la información del Producto con éxito.")
                    Return ProductoBE
                Else
                    detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.Catalogo_RegistroInexistenteOInactivo,
                                                 "No se obtuvo la información del Producto." & vbCrLf & detResp.Mensajes)
                    Return Nothing
                End If
            Else
                detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ValoresInvalidos,
                                         "La Clave del Producto contiene valor invalido " & vbCrLf & detResp.Mensajes)
                Return Nothing
            End If
        Catch ex As Exception
            Log.LogException(ex, "ProductoBL.GetProducto")
            detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ExcepcionEnOperacion,
                                        detResp.Mensajes & "Excepción al obtener información del Producto: " & ex.Message)
            Return Nothing
        Finally
            ProductoDAL = Nothing
            ProductoBE = Nothing
        End Try
    End Function

    Private Function EsValidoParaGetProducto(ByRef Clave As String, ByRef mensaje As String) As Boolean
        mensaje = ""
        Try
            If (String.IsNullOrEmpty(Clave)) Then
                mensaje &= "El campo Clave del Producto no puede ir  vacio." & vbCrLf
            End If

            Return (mensaje = "")
        Catch ex As Exception
            Log.LogException(ex, "ProductoBL.EsValidoParaGetProducto")
            mensaje &= ex.Message
            Return False
        End Try
    End Function

    Public Function GetListadoProducto(ByVal tokenConexion As String, ByVal Clave As String, ByVal Nombre As String, ByVal UdeM As Integer,
                                       ByVal Status As Enumeraciones.estatusParaBusquedas,
                                       ByVal pRegistroInicial As Integer, ByVal pPageSize As Integer,
                                       ByVal pSortColumn As Enumeraciones.campoOrdenamiento, ByVal pSortDirection As Enumeraciones.tipoOrdenamiento,
                                       ByRef pTotalRegistros As Integer,
                                       ByRef detResp As DetalleRespuesta) As List(Of ProductoBE)
        detResp.Mensajes = ""
        pTotalRegistros = 0
        Dim ProductoDAL As ProductoDAL = New ProductoDAL("")
        Dim listProductoBE As List(Of ProductoBE)
        Try
            tokenConexion = RijndaelSimple.desencriptaDefault(tokenConexion)
            ProductoDAL = New ProductoDAL(tokenConexion)
            listProductoBE = ProductoDAL.getListadoProducto(Clave, Nombre, UdeM, Status, pRegistroInicial, pPageSize, pSortColumn, pSortDirection, pTotalRegistros)
            If (listProductoBE IsNot Nothing) Then
                detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ProcesamientoOK,
                                         "Se obtuvo el listado de Productos con éxito.")
                Return listProductoBE
            Else
                detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.Catalogo_NoObtuvoRegistrosParaListado,
                                         "No se obtuvo el listado de los Productos." & vbCrLf & detResp.Mensajes)
                Return Nothing
            End If
        Catch ex As Exception
            Log.LogException(ex, "ProductoBL.GetListadoProducto")
            detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ExcepcionEnOperacion,
                                        detResp.Mensajes & "Excepción al obtener el listado de Productos: " & ex.Message)
            Return Nothing
        Finally
            ProductoDAL = Nothing
            listProductoBE = Nothing
        End Try
    End Function

    Public Function CambiaEstatus(ByVal tokenConexion As String, ByVal Clave As String, ByVal setActivo As Boolean,
                                           ByRef detResp As DetalleRespuesta) As Boolean
        detResp.Mensajes = ""
        Dim prodDAL As ProductoDAL = New ProductoDAL("")
        Try
            If (EsValidoParaGetProducto(Clave, detResp.Mensajes)) Then
                prodDAL = New ProductoDAL(RijndaelSimple.desencriptaDefault(tokenConexion))
                If (prodDAL.cambiaStatus(Clave, setActivo)) Then
                    detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ProcesamientoOK,
                                             "Estatus del Producto Actualizado.")
                    Return True
                Else
                    detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.Catalogo_NoFueActualizado,
                                             "No se pudo realizar la actualización de estatus del Producto." & vbCrLf &
                                             "Verifique que la Clave del Producto esté registrado en el sistema." & vbCrLf & detResp.Mensajes)
                    Return False
                End If
            Else
                detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ValoresInvalidos,
                                         "La informacion no es valida para actualizar: " & vbCrLf & detResp.Mensajes)
                Return False
            End If
        Catch ex As Exception
            Log.LogException(ex, "ProductoBL.CambiaEstatus")
            detResp.estableceValores(DetalleRespuesta.CodigoRespuesta.ExcepcionEnOperacion,
                                     detResp.Mensajes & "Excepción al actualizar estatus del Producto: " & ex.Message)
            Return False
        Finally
            prodDAL = Nothing
        End Try
    End Function

End Class
